package com.xhwl.data.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import com.xhwl.common.annotation.View;
import com.xhwl.common.dto.cent.face.QueryFaceDTO;
import com.xhwl.common.dto.cent.sdata.OrganizationDTO;
import com.xhwl.common.dto.cent.sdata.PermissionGroupDTO;
import com.xhwl.common.dto.cent.sdata.RoleTypeDTO;
import com.xhwl.common.enums.CodeEnum;
import com.xhwl.common.enums.CredentialsEnum;
import com.xhwl.common.enums.config.BusinessType;
import com.xhwl.common.enums.config.RoleTypeEnum;
import com.xhwl.common.enums.healthaged.EducationLevelEnum;
import com.xhwl.common.enums.healthaged.NationTypeEnum;
import com.xhwl.common.enums.healthaged.PoliticalOutlookEnum;
import com.xhwl.common.enums.personal.StaffStateEnum;
import com.xhwl.common.enums.personal.StaffTypeEnum;
import com.xhwl.common.enums.sdata.EnterpriseTypeEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.personnel.*;
import com.xhwl.common.pojo.msg.NoticeData;
import com.xhwl.common.pojo.msg.Target;
import com.xhwl.common.query.cent.sdata.*;
import com.xhwl.common.utils.CompressUtil;
import com.xhwl.common.utils.FileUtil;
import com.xhwl.common.utils.ValidatorUtil;
import com.xhwl.common.utils.excel.ExcelUtils;
import com.xhwl.common.vo.cent.face.QueryFaceVO;
import com.xhwl.data.dao.IAccountDao;
import com.xhwl.data.dao.IEnterpriseDao;
import com.xhwl.data.dao.devplatform.IDeveloperDao;
import com.xhwl.data.pojo.dto.personal.StaffExcelDTO;
import com.xhwl.data.pojo.dto.personal.StaffExcelErrorDTO;
import com.xhwl.data.pojo.dto.personal.StaffOrganizationEditDTO;
import com.xhwl.data.pojo.dto.personal.StaffQueryPageDTO;
import com.xhwl.data.pojo.personal.*;
import com.xhwl.data.service.*;
import com.xhwl.data.service.personal.*;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 企业员工
 * @Author: luyi
 * @Description: 企业员工
 * @Date: Create in 15:30 2022/2/8
 */
@RestController
public class StaffController {

    @Autowired
    private IStaffService staffService;

    @Autowired
    private IAccountService accountService;

    @Autowired
    IMessageCentService messageCentService;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private IStaffOrganizationService staffOrganizationService;

    @Autowired
    private IAccountRoleService accountRoleService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IStaffExcelImportService staffExcelImportService;

    @Autowired
    private IStaffExcelErrorService staffExcelErrorService;

    @Autowired
    private IPositionService positionService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IFaceManageService faceManageService;

    @Autowired
    private IStaffExtraDefinedService staffExtraDefinedService;

    @Autowired
    private IStaffBusinessTypeService staffBusinessTypeService;

    @Autowired
    private IStaffExtraService staffExtraService;

    @Autowired
    private IOrganizationTypeService organizationTypeService;

    @Autowired
    private IAccountOrganizationService accountOrganizationService;

    @Autowired
    private IStaffBusinessRelationService staffBusinessRelationService;

    @Autowired
    private IOrganizationManagerService organizationManagerService;

    @Autowired
    private IPermissionGroupService permissionGroupService;

    @Autowired
    private IEnterpriseDao enterpriseDao;

    @Autowired
    private IAccountDao accountDao;

    @Autowired
    IDeveloperDao developerDao;

    private static final String STAFF_PAGE_FIELD = "STAFF_PAGE_FIELD";

    private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    private static final Logger log = LoggerFactory.getLogger(StaffController.class);

    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private IEnterpriseSpaceService enterpriseSpaceService;

    @Autowired
    private IEnterpriseExtraService enterpriseExtraService;

    /**
     * 创建员工
     * @param staffDTO
     * @return
     */
    @RequestMapping(value = "/staff/create")
    public ResultJson create(@RequestHeader short industryId,
                             @RequestBody StaffDTO staffDTO, Account account){
        staffDTO.setIndustryId(industryId);
        staffDTO.setCurrentIndustryId(Integer.valueOf(industryId));
        if(null == account){
            return ResultJson.fail("获取登录信息失败");
        }
        if(null != staffDTO.getId()){
            return staffService.edit(staffDTO, account);
        }else{
            if(CollectionUtils.isNotEmpty(staffDTO.getRoleIds())){
                // 过滤掉非法的角色id
                staffDTO.setRoleIds(staffDTO.getRoleIds().stream().filter(i -> i > 0).collect(Collectors.toList()));
            }
            return staffService.create(staffDTO, account);
        }
    }

    /**
     * 删除（离职）员工
     * @param staffId
     * @param account
     * @return
     */
    @RequestMapping(value = "/staff/delete")
    public ResultJson delete(@RequestHeader("industryId") Integer industryId, Integer staffId, Account account){
        return staffService.delete(industryId, staffId, account);
    }

    /**
     * 批量删除 批量离职 2023-8迭代对整个组织的人员进行操作离职
     * @param staffIds
     * @param account
     * @return
     */
    @RequestMapping(value = "/staff/batch-delete")
    public ResultJson batchDelete(@RequestHeader("industryId") Integer industryId,
                                  @RequestPart(required = false)List<Integer> staffIds,
                                  @RequestPart(required = false)List<Integer> orgIds, Account account){
        if(CollectionUtils.isEmpty(staffIds) && CollectionUtils.isEmpty(orgIds)){
            return ResultJson.fail("参数错误");
        }
        StaffQuery staffQuery = new StaffQuery();
        List<StaffDTO> list = new ArrayList<>();
        if (null != staffIds && !staffIds.isEmpty()){
            staffQuery.setIds(staffIds);
            list = staffService.list(staffQuery);
        }
        if (null != orgIds && !orgIds.isEmpty()){
            staffQuery = new StaffQuery();
            staffQuery.setOrgIds(orgIds);
            staffQuery.setShowCurrent(false);
            list.addAll(staffService.list(staffQuery));
        }
        list = list.stream().distinct().collect(Collectors.toList());
        if(list.size() > 100){
            return ResultJson.fail("数量超过限制");
        }
        List<String> errors = new ArrayList<>();
        for (StaffDTO staff : list) {
            ResultJson delete = staffService.delete(industryId, staff.getId(), account);
            if(!delete.getState()){
                errors.add(staff.getName());
            }
        }
        if(errors.size() > 0){
            return ResultJson.fail(Joiner.on(",").join(errors) + "删除失败");
        }
        return ResultJson.success();
    }

    @RequestMapping(value = "/staff/edit-org")
    public ResultJson editOrg(@RequestBody StaffOrganizationEditDTO staffOrganizationEditDTO){
        if(null == staffOrganizationEditDTO.getStaffId() || CollectionUtils.isEmpty(staffOrganizationEditDTO.getOrgIds())){
            return ResultJson.fail("参数错误");
        }
        if(null == staffOrganizationEditDTO.getEnterpriseId()){
            return ResultJson.fail("缺少企业信息");
        }
        if(null == staffOrganizationEditDTO.getStaffId()){
            return ResultJson.fail("缺少员工信息");
        }
        Staff staff = staffService.getById(staffOrganizationEditDTO.getStaffId());
        if(null == staff){
            return ResultJson.fail("数据错误");
        }
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.withIds(staffOrganizationEditDTO.getOrgIds());
        List<Organization> list = organizationService.list(organizationQuery);
        if(list.isEmpty()){
            return ResultJson.fail("组织不存在");
        }
        List<Integer> collect = list.stream().map(i -> i.getId()).collect(Collectors.toList());

        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.eq("staff_id", staffOrganizationEditDTO.getStaffId());
        staffOrganizationQueryWrapper.eq("enterprise_id", staffOrganizationEditDTO.getEnterpriseId());
        List<Integer> orgIds1 = staffOrganizationService.list(staffOrganizationQueryWrapper).stream().distinct().map(i -> i.getOrgId()).collect(Collectors.toList());
        collect.removeAll(orgIds1);

        // 保存
        saveStaffOrganization(collect, staffOrganizationEditDTO.getStaffId(), staffOrganizationEditDTO.getEnterpriseId(), staff.getAccountId());
        // 需要删除的
        if(!CollectionUtils.isEmpty(staffOrganizationEditDTO.getDeletedOrgIds())){
            QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper1 = new QueryWrapper<>();
            staffOrganizationQueryWrapper1.eq("staff_id", staffOrganizationEditDTO.getStaffId());
            staffOrganizationQueryWrapper1.in("org_id", staffOrganizationEditDTO.getDeletedOrgIds());
            staffOrganizationService.remove(staffOrganizationQueryWrapper1);

            //是否是之前组织负责人，是则移除身份
            QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
            organizationManagerQueryWrapper.in("org_id",orgIds1);
            organizationManagerQueryWrapper.eq("account_id",staff.getAccountId());
            organizationManagerService.remove(organizationManagerQueryWrapper);
        }

        return ResultJson.success();
    }

    private void saveStaffOrganization(List<Integer> collect, Integer staffId, Integer entId, Integer accountId){
        List<StaffOrganization> createList = new ArrayList<>(collect.size());
        for (Integer integer : collect) {
            StaffOrganization staffOrganization = new StaffOrganization();
            staffOrganization.setStaffId(staffId);
            staffOrganization.setOrgId(integer);
            staffOrganization.setEnterpriseId(entId);
            staffOrganization.setAccountId(accountId);
            createList.add(staffOrganization);
        }
        staffOrganizationService.saveBatch(createList);
    }

    @RequestMapping(value = "/staff/batch-edit-org")
    public ResultJson batchEditOrg(@RequestBody StaffOrganizationEditDTO staffOrganizationEditDTO){
        if((CollectionUtils.isEmpty(staffOrganizationEditDTO.getStaffIds())
                && CollectionUtils.isEmpty(staffOrganizationEditDTO.getStaffOrgIds()))
                || CollectionUtils.isEmpty(staffOrganizationEditDTO.getOrgIds())){
            return ResultJson.fail("参数错误");
        }
        if(null == staffOrganizationEditDTO.getEnterpriseId()){
            return ResultJson.fail("缺少企业信息");
        }
        //通过组织选人
        if (CollectionUtils.isNotEmpty(staffOrganizationEditDTO.getStaffOrgIds())){
            //查找组织子节点（包括当前组织）
            List<Organization> organizationList = organizationService.child(new OrganizationQuery().withIds(staffOrganizationEditDTO.getStaffOrgIds()));
            QueryWrapper<StaffOrganization> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("org_id",organizationList.stream().map(Organization::getId).collect(Collectors.toList()));
            List<StaffOrganization> staffOrganizations = staffOrganizationService.list(queryWrapper);
            if (!staffOrganizations.isEmpty()){
                List<Integer> staffIds = staffOrganizations.stream().map(StaffOrganization::getStaffId).collect(Collectors.toList());
                staffOrganizationEditDTO.getStaffIds().addAll(staffIds);
            }
        }
        return staffService.batchEditOrg(staffOrganizationEditDTO.getStaffIds(), staffOrganizationEditDTO.getOrgIds(), staffOrganizationEditDTO.getEnterpriseId());
    }

    /**
     * 员工信息和帐号绑定
     * @return
     */
    @RequestMapping(value = "/staff/bind")
    public ResultJson bind(@RequestBody StaffDTO staffDTO, Account account){
        return staffService.bind(staffDTO, account);
    }

    /**
     * 判断手机号在账号表里是否存在
     * @return
     */
    @RequestMapping(value = "/staff/phone-exist-check")
    public ResultJson phoneCheck(@RequestParam(required = false) Integer staffId, @RequestParam(required = false) Integer enterpriseId, String phone, Account operator){
        if(StringUtils.isEmpty(phone)){
            return ResultJson.fail("参数错误");
        }
        Account account = accountService.phoneExistV2(phone, operator.getDevelopId());
        // 不能添加 需要绑定
        if(null != account){
            // 企业员工必须关联组织
            QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
            staffOrganizationQueryWrapper.select("id");
            staffOrganizationQueryWrapper.eq("account_id", account.getId());
            if(null != enterpriseId){
                staffOrganizationQueryWrapper.eq("enterprise_id", enterpriseId);
            }
            List<StaffOrganization> list = staffOrganizationService.list(staffOrganizationQueryWrapper);
            // 已经绑定过了
            if(CollectionUtils.isNotEmpty(list)){
                return ResultJson.fail("帐号已存在，不可以重复添加");
            }else{
                return ResultJson.success(CodeEnum.CAN_BIND.code, CodeEnum.CAN_BIND.description);
            }
        }
        return ResultJson.success();
    }

    /**
     * pc端员工详情
     * @param id
     * @param enterpriseId
     * @param accountId
     * @return
     */
    @RequestMapping(value = "/staff/detail")
    public ResultJson detail(@RequestParam(required = false) Integer id, Integer enterpriseId,
                             @RequestParam(required = false) Integer accountId,
                             @RequestHeader Integer industryId){
        if((null == id && null == accountId) || null == enterpriseId){
            return ResultJson.fail("参数错误");
        }
        StaffDTO staff = staffService.detail(id, enterpriseId, accountId, industryId);
        return ResultJson.success(staff);
    }

    /**
     * 移动端员工详情
     * @param id
     * @param enterpriseId
     * @param accountId
     * @return
     */
    @RequestMapping(value = "/staff/mobile/detail")
    public ResultJson mobileDetail(Integer id, Integer enterpriseId,
                                   @RequestParam(required = false) Integer accountId,
                                   @RequestHeader Integer industryId){
        if((null == id && accountId == enterpriseId) || null == enterpriseId){
            return ResultJson.fail("参数错误");
        }
        StaffDTO staff = staffService.detail(id, enterpriseId, accountId, industryId);
        if(null != staff.getShowPhone() && !staff.getShowPhone()){
            staff.setPhone("-");
        }
        return ResultJson.success(staff);
    }

    /**
     * 根据 企业idList 查询员工数量
     * @param enterpriseIdList
     * @return
     */
    @RequestMapping(value = "/staff/find-byEnterpriseIdList", method = RequestMethod.GET)
    public ResultJson findByEnterpriseIdList(@RequestParam List<Integer> enterpriseIdList) {
        if (enterpriseIdList == null) {
            return ResultJson.fail("参数错误,业务id输入为空");
        }
        return ResultJson.success(staffService.findByEnterpriseIdList(enterpriseIdList));
    }


    /**
     * 根据 业务类型id 查询员工数量
     * @param businessIdList
     * @param entId
     * @return
     */
    @RequestMapping(value = "/staff/find-byBusinessIdList", method = RequestMethod.GET)
    public ResultJson findByBusinessIdList(@RequestParam List<Integer> businessIdList, Integer entId) {
        if (businessIdList.isEmpty() || null == entId) {
            return ResultJson.fail("参数错误,业务id输入为空");
        }
        List returnList = staffService.findByBusinessIdList(businessIdList, entId);
        return ResultJson.success(returnList);
    }

    /**
     * 查询园区下所有账号数量、员工数量、公司员工数及排名
     * @return
     */
    @RequestMapping(value = "/staff/find-all-staff", method = RequestMethod.GET)
    public ResultJson findAllStaffs(){
        return ResultJson.success(staffService.findAllStaffs());
    }

    /**
     * @deprecated /staff/detail 代替
     * @param staffQuery
     * @return
     */
    @Deprecated
    @RequestMapping(value = "/staff/one")
    public ResultJson one(@RequestBody StaffQuery staffQuery){
        StaffDTO staff = staffService.one(staffQuery);
        return ResultJson.success(staff);
    }

    /**
     * 员工分页查询
     * @param staffQueryPageDTO
     * @return
     */
    @RequestMapping(value = "/staff/page")
    public ResultJson page(@RequestBody StaffQueryPageDTO staffQueryPageDTO, Account operator){
        Page page = staffQueryPageDTO.getPage() == null ? new Page():staffQueryPageDTO.getPage();
        OrderItem item = new OrderItem();
        item.setColumn("CONVERT( ss.name USING gbk ) COLLATE gbk_chinese_ci");
        page.setOrders(Arrays.asList(item));

        Page<StaffDTO> staffPage = staffService.page(staffQueryPageDTO.getStaffQuery(), page);
        operatorPermission(operator, staffPage.getRecords(),staffQueryPageDTO.getStaffQuery().getEnterpriseId());
        return ResultJson.success(staffPage);
    }

    private void operatorPermission(Account operator, List<StaffDTO> records,Integer enterpriseId) {
        if(!CollectionUtils.isEmpty(records)){
            List<Integer> accountIds = records.stream().map(i -> i.getAccountId()).collect(Collectors.toList());
            RoleTypeDTO accountRoleType = roleService.getAccountRoleType(operator.getId());
            Map<Integer, Boolean> updateMap = accountService.updateAccountCheckBatch(operator.getIndustryId(), accountRoleType.getRoleTypeEnum(), accountIds);
            Map<Integer, Boolean> deleteMap = accountService.deleteAccountCheckBatch(operator.getIndustryId(), accountRoleType.getRoleTypeEnum(), accountIds,enterpriseId);
            for (StaffDTO record : records) {
                try {
                    record.setCanUpdate(updateMap.get(record.getAccountId()));
                } catch (Exception e){
                    record.setCanUpdate(false);
                    log.warn("数据错误，账号 {} 获取更新权限失败", record.getAccountId());
                }
                try {
                    record.setCanDelete(deleteMap.get(record.getAccountId()));
                }catch (Exception e){
                    record.setCanDelete(false);
                    log.warn("数据错误，账号 {} 获取删除权限失败", record.getAccountId());
                }
            }
        }
    }

    /**
     * 所有员工
     *
     * @param staffQuery
     * @return
     */
    @RequestMapping(value = "/staff/list")
    public ResultJson list(@RequestBody StaffQuery staffQuery){
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("enterprise_id",staffQuery.getEnterpriseId());
        List<Role> roles = roleService.list(roleQueryWrapper);

        List<Integer> idList = new ArrayList<>();
        roles.forEach(role->{
            if(staffQuery.getWorkCodes().contains(role.getName())){
                idList.add(role.getId());
            }
        });

        if(CollectionUtils.isNotEmpty(idList)) {
            staffQuery.setRoleId(idList);
        }
        staffQuery.setWorkCodes(null);
        List<StaffDTO> list = staffService.list(staffQuery);
        List<StaffDTO> retStaffList = new ArrayList<>();
        List<Integer> accoundIdList = list.stream().map(StaffDTO::getAccountId).collect(Collectors.toList());
        QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.in("id",accoundIdList);
        List<Account> accountList = accountService.list(accountQueryWrapper);
        list.forEach(staff->{
            Account account = accountList.stream().filter(s->s.getId().equals(staff.getAccountId())).findAny().orElse(null);
            if(account !=null && StringUtils.isNotEmpty(account.getPassword())) {
                staff.setPassword(account.getPassword());
                List<Role> roleList = roleService.getRoleListByAccountId(staff.getAccountId());
                staff.setRoleIds(roleList.stream().map(Role::getId).collect(Collectors.toList()));
                staff.setRoleNames(roleList.stream().map(Role::getName).collect(Collectors.toList()));
                retStaffList.add(staff);
            }
        });
        return ResultJson.success(retStaffList);
    }

    /**
     * pc端离职员工详情
     * @param id 离职id
     * @return
     */
    @RequestMapping(value = "/staff/delete/detail")
    public ResultJson deleteDetail(Integer id){
        StaffDTO staff = staffService.deleteDetail(id);
        return ResultJson.success(staff);
    }

    /**
     * 员工类型
     * @return
     */
    @RequestMapping(value = "/staff/type")
    public ResultJson staffType(){

        List<Map<String, Object>> result = new ArrayList<>();
        for (StaffTypeEnum value : StaffTypeEnum.values()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", value.id);
            map.put("name", value.description);
            result.add(map);
        }
        return ResultJson.success(result);
    }

    /**
     * 员工状态
     * @return
     */
    @RequestMapping(value = "/staff/state")
    public ResultJson staffState(){
        List<Map<String, Object>> result = new ArrayList<>();
        for (StaffStateEnum value : StaffStateEnum.values()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", value.id);
            map.put("name", value.description);
            result.add(map);
        }
        return ResultJson.success(result);
    }

    /**
     * 移除组织关系
     * @param orgId
     * @param staffId
     * @return
     */
    @RequestMapping(value = "/staff/remove-org")
    public ResultJson removeOrg(Integer orgId, Integer staffId){

        if(null == orgId || null == staffId){
            return ResultJson.fail("参数错误");
        }
        Organization organization = organizationService.getById(orgId);
        if(null == organization){
            return ResultJson.fail("组织不存在");
        }
        Staff staff = staffService.getById(staffId);
        QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
        organizationManagerQueryWrapper.eq("account_id",staff.getAccountId());
        organizationManagerQueryWrapper.eq("org_id",orgId);
        //如果是组织负责人，先移除负责人
        if (null != organizationManagerService.getOne(organizationManagerQueryWrapper)){
            organizationManagerService.remove(organizationManagerQueryWrapper);
        }
        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.eq("staff_id", staffId);
        staffOrganizationQueryWrapper.eq("org_id", orgId);
        staffOrganizationService.remove(staffOrganizationQueryWrapper);
        return ResultJson.success();
    }

    /**
     * 移除项目
     * @return
     */
    @RequestMapping(value = "/staff/remove-project")
    public ResultJson removeProject(Integer staffId, Integer projectId){
        if(null == staffId || null == projectId){
            return ResultJson.fail("参数错误");
        }
        staffService.removeProject(staffId, projectId);
        return ResultJson.success();
    }

    /**
     * 移除角色
     * @return
     */
    @RequestMapping(value = "/staff/remove-role")
    public ResultJson removeRole(Integer staffId, Integer roleId){
        if(null == staffId || null == roleId){
            return ResultJson.fail("参数错误");
        }
        Staff staff = staffService.getById(staffId);
        if(null == staff){
            return ResultJson.fail("员工信息不存在");
        }
        accountRoleService.deleteAccountRole(Arrays.asList(staff.getAccountId()), Arrays.asList(roleId));
        return ResultJson.success();
    }

    @RequestMapping(value = "/staff/org/count-staff")
    public ResultJson countStaff(@RequestBody List<Integer> orgIds){
        if(CollectionUtils.isEmpty(orgIds)){
            return ResultJson.fail("参数错误");
        }
        List<OrgStaffCount> result = new ArrayList<>(orgIds.size());
        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.in("org_id", orgIds);
        List<StaffOrganization> list = staffOrganizationService.list(staffOrganizationQueryWrapper);
        Map<Integer, List<Integer>> orgAccountMap = list.stream().collect((Collectors.groupingBy(StaffOrganization::getOrgId, Collectors.mapping(StaffOrganization::getAccountId, Collectors.toList()))));
        for (Integer orgId : orgIds) {
            OrgStaffCount orgStaffCount = new OrgStaffCount();
            orgStaffCount.setOrgId(orgId);
            orgStaffCount.setCount(orgAccountMap.get(orgId).size());
            result.add(orgStaffCount);
        }
        return ResultJson.success(result);
    }


    @PostMapping("/staff/org-tree")
    public ResultJson orgTree(Integer projectId, Account account){
        List<OrganizationDTO> result = staffService.orgTree(projectId, account.getId());
        return ResultJson.success(result);
    }

    /**
     *
     * @param file
     * @param projectId 导入的项目角色为该项目下的， 企业角色为该项目所在企业下的
     * @return
     */
    @RequestMapping(value = "/staff/import")
    public ResultJson importExcel(@RequestParam MultipartFile file,@RequestHeader("industryId") Integer industryId, @RequestParam Integer projectId, Account account, @RequestParam Integer enterpriseId){
        List<StaffExcelDTO> staffExcelDTOS = ExcelUtils.readExcel(StaffExcelDTO.class, file, 3);
        if(staffExcelDTOS.isEmpty()){
            return ResultJson.fail("空数据");
        }
        List<StaffExcelDTO> staffExcelDTOList = staffExcelDTOS.stream().filter(i -> i.getName() != null && i.getPassword() != null && i.getPhone() != null && i.getOrgCode() != null).collect(Collectors.toList());
        try {
            InputStream is = file.getInputStream();
            Workbook workbook = new XSSFWorkbook(is);
            Sheet sheet = workbook.getSheetAt(0);
            //从第三行开始读取权限组数据（和readExcel开始解析的行数一致）
            int i = 3;
            for (StaffExcelDTO staffExcelDTO : staffExcelDTOList){
                Row row = sheet.getRow(i);
                if (null == row){
                    continue;
                }
                List<PermissionGroupDTO> permissionGroupDTOS = new ArrayList<>();
                for (int j = 5; j < 11; j++){
                    Cell cell = row.getCell(j);
                    Cell cell1 = row.getCell(j + 1);
                    String cellValue = null;
                    if(cell != null){
                        cell.setCellType(CellType.STRING);//转化为文本类型
                        cellValue = StringUtils.trimToEmpty(cell.getStringCellValue());
                    }
                    String cellValue1 = null;
                    if(cell1 != null){
                        cell1.setCellType(CellType.STRING);//转化为文本类型
                        cellValue1 = StringUtils.trimToEmpty(cell1.getStringCellValue());

                    }
                    PermissionGroupDTO permissionGroupDTO = new PermissionGroupDTO();
                    if (StringUtils.isEmpty(cellValue)){
                        continue;
                    }
                    if (StringUtils.isNotEmpty(cellValue1)){
                        List<String> projectNames = Arrays.asList(cellValue1.split(","));
                        permissionGroupDTO.setProjectNames(projectNames);
                    }
                    List<String> roleNames = Arrays.asList(cellValue.split(","));
                    permissionGroupDTO.setRoleNames(roleNames);
                    j ++;
                    permissionGroupDTOS.add(permissionGroupDTO);
                }
                i++;
                staffExcelDTO.setPermissionGroupDTOS(permissionGroupDTOS);
            }
        }catch (Exception e){
            log.error(String.format("parse excel exception!"), e);
        }
        Project project = projectService.findById(projectId);
        if(null == project){
            return ResultJson.fail("项目不存在");
        }
        String errorId = UUID.randomUUID().toString().replaceAll("-", "");
//        singleThreadExecutor.submit(new Runnable() {
//            @Override
//            public void run() {
//
//            }
//        });
        ImportResult importResult = importHandler(project, staffExcelDTOList, account, errorId, file.getOriginalFilename(),enterpriseId,industryId);
        importResult.setFileId(errorId);
        return ResultJson.success(importResult);
    }

    @RequestMapping(value = "/staff/import-history")
    public ResultJson importHistory(@RequestBody StaffExcelImportQuery query){

        if(null == query.getEnterpriseId()){
            return ResultJson.fail("参数错误");
        }
        QueryWrapper<StaffExcelImport> staffExcelImportQueryWrapper = new QueryWrapper<>();
        staffExcelImportQueryWrapper.eq("enterprise_id", query.getEnterpriseId());
        if(StringUtils.isNotEmpty(query.getFileName())){
            staffExcelImportQueryWrapper.like("file_name", query.getFileName());
        }
        Page page1 = query.getPage();
        page1.setOrders(Arrays.asList(OrderItem.desc("created_at")));
        Page<StaffExcelImport> page = staffExcelImportService.page(page1, staffExcelImportQueryWrapper);
        return ResultJson.success(page);
    }

    @RequestMapping(value = "/staff/export-error")
    public void export(HttpServletResponse response, @RequestParam String fileId){

        QueryWrapper<StaffExcelImport> staffExcelImportQueryWrapper = new QueryWrapper<>();
        staffExcelImportQueryWrapper.eq("file_id", fileId);
        List<StaffExcelImport> list1 = staffExcelImportService.list(staffExcelImportQueryWrapper);
        if(list1.isEmpty()){
            throw new BusinessException("文件不存在");
        }

        QueryWrapper<StaffExcelError> staffExcelErrorQueryWrapper = new QueryWrapper<>();
        staffExcelErrorQueryWrapper.eq("file_id", fileId);
        List<StaffExcelError> list = staffExcelErrorService.list(staffExcelErrorQueryWrapper);

        List<StaffExcelErrorDTO> exportList = new ArrayList<>(list.size());
        for (StaffExcelError staffExcelError : list) {
            String obj = staffExcelError.getObj();
            StaffExcelErrorDTO staffExcelErrorDTO = JSON.parseObject(obj, StaffExcelErrorDTO.class);
            staffExcelErrorDTO.setReason(staffExcelError.getReason());
            exportList.add(staffExcelErrorDTO);
        }

        exportErrorHandler(response, exportList, fileId);
    }

  /**
     * 导出组织员工
     * @param response
     * @param staffQuery
     */
    @RequestMapping(value = "/staff/export-org")
    public void exportOrg(HttpServletResponse response, @RequestBody StaffQuery staffQuery){

        long start = System.currentTimeMillis();
        List<StaffDTO> staffs = staffService.list(staffQuery);
        long time2 = System.currentTimeMillis();
        log.info("spend {}", (time2 -start));
        if(staffs.isEmpty()){
            throw new BusinessException("空数据");
        }

        List<StaffExcelDTO> exportList = new ArrayList<>(staffs.size());
        long time3 = System.currentTimeMillis();
        log.info("spend2 {}", (time3 - time2));
        StaffFieldMap staffFieldMap = staffService.staffFieldViewHandler(staffs);
        for (StaffDTO staff : staffs) {
            StaffExcelDTO staffDTO = new StaffExcelDTO();
            BeanUtils.copyProperties(staff, staffDTO);
            if(null != staff.getSex()){
                staffDTO.setSex(staff.getSex() == (short)1 ? "男":"女");
            }
            try {
                List<String> strings = staffFieldMap.getDeptMap().get(staff.getId()).stream().map(i -> i.getName()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(strings)){
                    staffDTO.setOrganization(Joiner.on(",").join(strings));
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            if(null != staff.getPositionId()){
                staffDTO.setPosition(staffFieldMap.getPositionMap().get(staff.getPositionId()));
            }
            if(null != staff.getStaffType()){
                staffDTO.setStaffTypeName(StaffTypeEnum.idOf(staff.getStaffType()));
            }
            if(null != staff.getStaffState()){
                staffDTO.setStaffStateName(StaffStateEnum.idOf(staff.getStaffState()));
            }
            if(CollectionUtils.isNotEmpty(staffFieldMap.getProjectMap().get(staff.getAccountId()))){
                staffDTO.setProjects(Joiner.on(",").join(staffFieldMap.getProjectMap().get(staff.getAccountId())));
            }
            if(CollectionUtils.isNotEmpty(staffFieldMap.getRoleMap().get(staff.getAccountId()))){
                staffDTO.setRoles(Joiner.on(",").join(staffFieldMap.getRoleMap().get(staff.getAccountId())));
            }
            //权限组
            if (CollectionUtils.isNotEmpty(staffFieldMap.getPermissionMap().get(staff.getAccountId()))){
                staffDTO.setPermissionGroupDTOS(staffFieldMap.getPermissionMap().get(staff.getAccountId()));
            }
            // 政治面貌
            if(null != staff.getPoliticsStatus()){
                staffDTO.setPoliticsStatusName(staff.getPoliticsStatus().name);
            }
            // 民族
            if(null != staff.getNation()){
                staffDTO.setNationName(staff.getNation().name);
            }
            // 学历
            if(null != staff.getEducationalLevel()){
                staffDTO.setEducationalLevelName(staff.getEducationalLevel().name);
            }
            // 业务类型
            if(null != staff.getBusinessNames()){
                String businessName = String.join(",",staff.getBusinessNames());
                staffDTO.setBusinessName(businessName);
            }
            // 上级
            if(null != staff.getHigherUp()){
                staffDTO.setHigherUpName(staffFieldMap.getUpNameMap().get(staff.getHigherUp()));
            }
            if(null != staff.getBirthday()){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                staffDTO.setBirthday(simpleDateFormat.format(staff.getBirthday()));
            }
            if(null != staff.getJoinTime()){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                staffDTO.setJoinTime(simpleDateFormat.format(staff.getJoinTime()));
            }
            if (null != staff.getWorkingTime()){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                staffDTO.setWorkingTime(simpleDateFormat.format(staff.getWorkingTime()));
            }
            if(StringUtils.isNotEmpty(staff.getCardNo()) && CredentialsEnum.ID_CARD == staff.getCardType()){
                staffDTO.setIdCard(staff.getCardNo());
            }
            exportList.add(staffDTO);
        }
        log.info("spend3 {}", (System.currentTimeMillis() - time3));

        exportHandler(response, exportList, UUID.randomUUID().toString().replaceAll("-", ""));
    }

    @RequestMapping(value = "/staff/export-template")
    public void exportTemplate(HttpServletResponse response,@RequestParam Integer enterpriseId){
        /*final String fileName = "STAFF_IMPORT_TEMPLATE.xlsx";
        String errorFilePath = getFilePath(fileName);
        FileInputStream is = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = null;
        try {
            is = new FileInputStream(errorFilePath);
            byte[] b = new byte[1024];
            int n;
            while ((n = is.read(b)) != -1){
                bos.write(b, 0, n);
            }
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("TEMPLATE.xlsx", "utf-8"));
            response.flushBuffer();
            response.getOutputStream().write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        final String fileName = "STAFF_IMPORT_TEMPLATE_NEW.xlsx";
        String filePath = getFilePath(fileName);
        File file = new File(filePath);
        if(file.exists()){
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=STAFF_IMPORT_TEMPLATE_NEW.xlsx");
            response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                Workbook workbook = null;
                try {
                    workbook = new XSSFWorkbook(fis);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //获得企业的组织
                QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("type", Arrays.asList(1,4));
                queryWrapper.eq("enterprise_id", enterpriseId);
                List<Organization> orgList = organizationService.list(queryWrapper);
                writeOrgInfo(orgList, workbook);
                workbook.write(response.getOutputStream());
            } catch (Exception e) {
                log.error(e.getMessage());
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }else{
            log.error("文件 {} 不存在", filePath);
        }
    }

    /**
     * 写组织数据
     * @param orgList
     * @param wb
     */
    public void writeOrgInfo(List<Organization> orgList, Workbook wb){
        if(CollectionUtils.isNotEmpty(orgList)){
            List<Map<String, String>> list = dealData(orgList);
            if(CollectionUtils.isEmpty(list)){
                return;
            }
            Sheet sheetAt = wb.getSheetAt(1);
            int i = 1;
            for (Map<String, String> vo : list) {
                Row row = sheetAt.createRow(i);
                Cell cell = row.createCell(0);
                cell.setCellValue(vo.get("name"));
                Cell cell1 = row.createCell(1);
                cell1.setCellValue(vo.get("code"));
                i++;
            }
        }
    }

    public List<Map<String,String>> dealData(List<Organization> orgList){
        List<Map<String,String>> result = new ArrayList<>();
        if(CollectionUtils.isEmpty(orgList)){
            return null;
        }
        Map<Integer, Organization> map = orgList.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
        Map<String,String> voMap = null;
        List<String> listName = null;
        for(Organization vo :orgList){
            voMap = new HashMap<>();
            listName = new ArrayList<>();
            listName.add(vo.getName());
            dealOrg(vo.getParentId(),map,listName);
            Collections.reverse(listName);
            voMap.put("name",Joiner.on("/").join(listName));
            voMap.put("code",vo.getCode());
            result.add(voMap);
        }
        return result;
    }

    /**
     * 递归组装数据
     */
    private void dealOrg(Integer parentId,Map<Integer,Organization> map,List<String> listName){
        if(map == null){
            return;
        }
        Organization organization = map.get(parentId);
        if(organization == null){
            return ;
        }
        listName.add(organization.getName());
        dealOrg(organization.getParentId(),map,listName);
    }

    @RequestMapping(value = "/staff/export-face")
    public void exportFaceZip(HttpServletResponse response, @RequestBody StaffQuery staffQuery){
        List<StaffDTO> staffs = staffService.list(staffQuery);
        if(staffs.isEmpty()){
            throw new BusinessException("空数据");
        }

        List<String> phone = staffs.stream().filter(i -> StringUtils.isNotEmpty(i.getPhone())).map(i -> i.getPhone()).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(phone)){
            log.warn("帐号未关联手机号");
            throw new DataException("数据错误");
        }
        QueryFaceDTO queryFaceDTO = new QueryFaceDTO();
        queryFaceDTO.setPhoneList(phone);
        List<QueryFaceVO> queryFaceVOS = faceManageService.queryFace(queryFaceDTO);
        if(queryFaceVOS.isEmpty()){
            throw new BusinessException("暂无人脸数据");
        }
        Map<String, String> map = new HashMap<>();
        for (QueryFaceVO faceVO : queryFaceVOS) {
            if(StringUtils.isNotEmpty(faceVO.getFaceUrl())){
                map.put(faceVO.getUsername(), faceVO.getFaceUrl());
            }
        }
        String randomFile = UUID.randomUUID().toString().replaceAll("-", "");
        String basePath = getFilePath("");
        String download = basePath + "/temp/" + randomFile;
        if(!map.isEmpty()){
            File file = new File(download);
            if(!file.exists()){
                file.mkdir();
            }

            for (Map.Entry<String, String> entry : map.entrySet()) {
                String u = entry.getValue();

                String fileName = u.substring(u.lastIndexOf("/"));
                String picName = entry.getKey() + fileName.substring(fileName.lastIndexOf("."));
                String fileAllName = download +"/"+ picName;
                File file1 = new File(fileAllName);
                URL url = null;
                try {
                    url = new URL(u);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
                try {
                    FileUtils.copyURLToFile(url, file1);
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }
            CompressUtil.compressFileToZip(download);
        }
        // 读取文件
        FileInputStream is = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = null;
        try {
            is = new FileInputStream(download + ".zip");
            byte[] b = new byte[1024];
            int n;
            while ((n = is.read(b)) != -1){
                bos.write(b, 0, n);
            }
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 删除文件
            FileUtil.delete(new File(basePath + "/temp"));
        }
        try {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("DOCUMENT.zip", "utf-8"));
            response.flushBuffer();
            response.getOutputStream().write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "/staff/get-staff-org")
    public ResultJson getStaffOrg(@RequestBody StaffQuery staffQuery){
        List<Integer> list = staffService.orgList(staffQuery);
        return ResultJson.success(list);
    }

    /**
     * 自动为当前企业下的非业态角色帐号生成员工信息，并全部关联到当前企业下
     * @return
     */
    @RequestMapping(value = "/staff/auto-import")
    public ResultJson autoImport(Integer enterpriseId, Account account){
        if(!roleService.isSuperManager(account.getId())){
            return ResultJson.fail("不是超级管理员");
        }
        return staffService.autoImport(enterpriseId);
    }

    private void exportHandler(HttpServletResponse response, List<StaffExcelDTO> data, String fileName) {
        final String fn = "STAFF_EXPORT_TEMPLATE.xlsx";
        String errorFilePath = getFilePath(fn);
        InputStream is = null;
        try {
            is = new FileInputStream(errorFilePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Workbook workbook = null;
        try {
            workbook = new XSSFWorkbook(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 设置格式
        Sheet sheet = workbook.getSheetAt(0);
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        Font font = workbook.createFont();
        cellStyle.setFont(font);
        ExcelUtils.setByColName(data, StaffExcelDTO.class, sheet, 1,2);
        //从第三行开始写
        int j = 2;
        for (StaffExcelDTO staffExcelDTO : data) {
            Row row = sheet.getRow(j);
            if (CollectionUtils.isEmpty(staffExcelDTO.getPermissionGroupDTOS())){
                continue;
            }
            int a = 0;
            //第四列开始
            for (int i = 3;i < 9;i ++){
                if (a >= staffExcelDTO.getPermissionGroupDTOS().size()){
                    continue;
                }
                Cell cell = row.createCell(i);
                Cell cell1 = row.createCell(i+1);
                String roleNames = StringUtils.join(staffExcelDTO.getPermissionGroupDTOS().get(a).getRoleNames().toArray(),",");
                if (CollectionUtils.isNotEmpty(staffExcelDTO.getPermissionGroupDTOS().get(a).getProjectNames())){
                    String projectNames = StringUtils.join(staffExcelDTO.getPermissionGroupDTOS().get(a).getProjectNames().toArray(),",");
                    cell1.setCellValue(projectNames);
                }
                cell.setCellValue(roleNames);
                i ++;
                a++;
            }
            j++;
        }
        ExcelUtils.buildExcelDocument(fileName + ".xlsx", workbook, response);
    }

    private void exportErrorHandler(HttpServletResponse response, List<StaffExcelErrorDTO> data, String fileName) {
        final String fn = "STAFF_EXPORT_ERROR_TEMPLATE.xlsx";
        String errorFilePath = getFilePath(fn);
        InputStream is = null;
        try {
            is = new FileInputStream(errorFilePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Workbook workbook = null;
        try {
            workbook = new XSSFWorkbook(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 设置格式
        Sheet sheet = workbook.getSheetAt(0);
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        Font font = workbook.createFont();
        cellStyle.setFont(font);
        ExcelUtils.setByColName(data, StaffExcelErrorDTO.class, sheet, 1,2);
        int j = 2;
        for (StaffExcelErrorDTO staffExcelErrorDTO : data) {
            Row row = sheet.getRow(j);
            if (CollectionUtils.isEmpty(staffExcelErrorDTO.getPermissionGroupDTOS())){
                continue;
            }
            int a = 0;
            //第五列开始
            for (int i = 4;i < 9;i ++){
                if (a >= staffExcelErrorDTO.getPermissionGroupDTOS().size()){
                    continue;
                }
                Cell cell = row.createCell(i);
                Cell cell1 = row.createCell(i+1);
                String roleNames = StringUtils.join(staffExcelErrorDTO.getPermissionGroupDTOS().get(a).getRoleNames().toArray(),",");
                if (CollectionUtils.isNotEmpty(staffExcelErrorDTO.getPermissionGroupDTOS().get(a).getProjectNames())){
                    String projectNames = StringUtils.join(staffExcelErrorDTO.getPermissionGroupDTOS().get(a).getProjectNames().toArray(),",");
                    cell1.setCellValue(projectNames);
                }
                cell.setCellValue(roleNames);
                i ++;
                a++;
            }
            j++;
        }
        ExcelUtils.buildExcelDocument(fileName + ".xlsx", workbook, response);
    }

    /**
     * 获取列表展示的字段
     * @param account
     * @return
     */
    @RequestMapping(value = "/staff/get-field-sort")
    public ResultJson getFieldSort(Account account){
        Set<String> range = redisTemplate.opsForZSet().range(STAFF_PAGE_FIELD + "_" + account.getId(), 0, -1);
        return ResultJson.success(range);
    }

    /**
     * 设置列表展示的字段
     * @param arr
     * @param account
     * @return
     */
    @RequestMapping(value = "/staff/set-field-sort")
    public ResultJson setFieldSort(@RequestBody List<String> arr, Account account){
        if(CollectionUtils.isEmpty(arr)){
            return ResultJson.fail("空数据");
        }
        Set<DefaultTypedTuple<String>> set = new HashSet<>();
        for(int i = 0; i < arr.size(); i ++){
            DefaultTypedTuple<String> tuple1 = new DefaultTypedTuple<String>(arr.get(i), Double.valueOf(i));
            set.add(tuple1);
        }
        redisTemplate.opsForZSet().removeRange(STAFF_PAGE_FIELD + "_" + account.getId(), 0, 100);
        redisTemplate.opsForZSet().add(STAFF_PAGE_FIELD + "_" + account.getId(), set);
        return ResultJson.success();
    }

    /**
     * 政治面貌
     * @return
     */
    @PostMapping("/staff/politics")
    public ResultJson politicsStatus(){
        PoliticalOutlookEnum[] values = PoliticalOutlookEnum.values();
        List<Map<String, Object>> result = new ArrayList<>();
        for (PoliticalOutlookEnum value : values) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", value.code);
            map.put("name", value.getName());
            result.add(map);
        }
        return ResultJson.success(result);
    }

    /**
     * 民族
     * @return
     */
    @PostMapping("/staff/nations")
    public ResultJson nation(){
        NationTypeEnum[] values = NationTypeEnum.values();
        List<Map<String, Object>> result = new ArrayList<>();
        for (NationTypeEnum value : values) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", value.code);
            map.put("name", value.name);
            result.add(map);
        }
        return ResultJson.success(result);
    }

    /**
     * 学历
     * @return
     */
    @PostMapping("/staff/education-level")
    public ResultJson educationLevel(){
        EducationLevelEnum[] values = EducationLevelEnum.values();
        List<Map<String, Object>> result = new ArrayList<>();
        for (EducationLevelEnum value : values) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", value.code);
            map.put("name", value.name);
            result.add(map);
        }
        return ResultJson.success(result);
    }

    /**
     * 新增 编辑 员工信心自定义表单
     * @param staffExtraDefined
     * @return
     */
    @PostMapping("/staff/extra-defined/create")
    public ResultJson staffExtraDefined(@RequestBody StaffExtraDefined staffExtraDefined){
        // 新增
        if(null == staffExtraDefined.getId()){
            return staffExtraDefinedService.create(staffExtraDefined);
        }else { // 编辑
            return staffExtraDefinedService.update(staffExtraDefined);
        }
    }

    /**
     * 证件类型
     * @return
     */
    @RequestMapping("/staff/card-type")
    public ResultJson cardType(){
        List<Map<String, Object>> result = new ArrayList<>();
        for (CredentialsEnum value : CredentialsEnum.values()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", value.name());
            map.put("name", value.description);
            result.add(map);
        }
        return ResultJson.success(result);
    }

    @PostMapping("/staff/extra-defined/page")
    public ResultJson staffExtraDefinedList(@RequestBody StaffExtraDefinedQuery query){
        if(null == query.getEnterpriseId()){
            return ResultJson.fail("参数错误");
        }
        Page<StaffExtraDefined> page = staffExtraDefinedService.page(query.getEnterpriseId(), query.getPage());
        return ResultJson.success(page);
    }

    @RequestMapping("/staff/extra-defined/detail")
    public ResultJson staffExtraDefinedDetail(Integer id){
        return ResultJson.success(staffExtraDefinedService.getById(id));
    }

    @RequestMapping("/staff/extra-defined/delete")
    public ResultJson staffExtraDefinedDelete(Integer id){
        return ResultJson.success(staffExtraDefinedService.removeById(id));
    }

    /**
     * 员工审核分页
     *
     * @param query
     * @param page
     * @return
     */
    @GetMapping("/staff/page-review-staff")
    public ResultJson pageReviewStaff(@RequestHeader("industryId")  Integer industryId,
                                      StaffAuditRecordQuery query, Page page) {
        if (null == query.getCurrentEnterpriseId() && null == query.getReviewEnterpriseId()) {
            return ResultJson.fail("企业ID不能为空");
        }
        return ResultJson.success(staffService.pageReviewStaff(query, page,industryId));
    }

    /**
     * 员工审核企业列表
     *
     * @param currentEnterpriseId
     * @return
     */
    @GetMapping("/staff/list-review-enterprise")
    public ResultJson listReviewEnterprise(@RequestParam("currentEnterpriseId") Integer currentEnterpriseId,
                                           @RequestParam(value = "likeEnterpriseName", required = false) String likeEnterpriseName) {
        return ResultJson.success(staffService.listReviewEnterprise(currentEnterpriseId, likeEnterpriseName));
    }

    /**
     * 审核
     *
     * @param industryId
     * @param recordId
     * @param pass
     * @return
     */
    @GetMapping("/staff/review")
    public ResultJson review(@RequestHeader("industryId") Integer industryId,
                             @RequestParam("recordId") Integer recordId,
                             @RequestParam("pass") Boolean pass,
                             @RequestParam("currentEnterpriseId") Integer currentEnterpriseId) {
        return staffService.review(recordId, pass, industryId,currentEnterpriseId);
    }

    /**
     * 批量审核
     *
     * @param recordIds
     * @param pass
     * @return
     */
    @GetMapping("/staff/batch-review")
    public ResultJson batchReview(@RequestHeader("industryId") Integer industryId,
                                  @RequestParam("recordIds") List<Integer> recordIds,
                                  @RequestParam("pass") Boolean pass,
                                  @RequestParam("currentEnterpriseId") Integer currentEnterpriseId) {
        if (recordIds.stream().distinct().count() < recordIds.size()) {
            return ResultJson.fail("提交审核记录ID重复");
        }
        if (recordIds.size() > 10) {
            return ResultJson.fail("一次最多提交审核10条记录");
        }
        return staffService.batchReview(recordIds, pass, industryId, currentEnterpriseId);
    }

    /**
     * 员工审核展示属性列表
     *
     * @return
     */
    @GetMapping("/staff/review/list-show-field")
    public ResultJson listReviewField(Account account) {
        List<JSONObject> list = Arrays.stream(StaffAuditRecord.class.getDeclaredFields())
                .filter(x -> null != x.getAnnotation(View.class))
                .map(x -> {
                    View view = x.getAnnotation(View.class);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("field", x.getName());
                    jsonObject.put("view", view.value());
                    jsonObject.put("selected", 0);
                    return jsonObject;
                }).collect(Collectors.toList());
        Set<String> selectedSet = redisTemplate.opsForZSet().range("STAFF_REVIEW_SHOW_FIELD" + "_" + account.getId(), 0, -1);
        if (CollectionUtils.isEmpty(selectedSet)) {
            list.forEach(x -> x.put("selected", 1));
            return ResultJson.success(list);
        }
        List<String> selectedList = new ArrayList<>(selectedSet);
        list.forEach(x -> {
            for (int i = 0; i < selectedList.size(); i++) {
                if (x.get("field").equals(selectedList.get(i))) {
                    x.put("selected", 1);
                    x.put("sort", i);
                    break;
                }
            }
        });
        AtomicInteger i = new AtomicInteger();
        List<JSONObject> sortList = list.stream().sorted(Comparator.comparingInt(x -> {
            if (x.containsKey("sort")) {
                return x.getInteger("sort");
            }
            return selectedSet.size() + i.incrementAndGet();
        })).collect(Collectors.toList());
        return ResultJson.success(sortList);
    }

    /**
     * 员工审核设置展示属性
     *
     * @return
     */
    @GetMapping("/staff/review/set-show-field")
    public ResultJson setReviewField(@RequestParam("showFields") List<String> showFields, Account account) {
        Set<DefaultTypedTuple<String>> set = new HashSet<>();
        for (int i = 0; i < showFields.size(); i++) {
            DefaultTypedTuple<String> tuple = new DefaultTypedTuple<String>(showFields.get(i), Double.valueOf(i));
            set.add(tuple);
        }
        redisTemplate.opsForZSet().removeRange("STAFF_REVIEW_SHOW_FIELD" + "_" + account.getId(), 0, 100);
        redisTemplate.opsForZSet().add("STAFF_REVIEW_SHOW_FIELD" + "_" + account.getId(), set);
        return ResultJson.success();
    }

    /**
     * 员工审核状态下拉框
     *
     * @return
     */
    @GetMapping("/staff/review/status")
    public ResultJson reviewStatus(@RequestParam("currentEnterpriseId") Integer currentEnterpriseId,
                                   @RequestParam("reviewEnterpriseId") Integer reviewEnterpriseId) {
        return ResultJson.success(staffService.reviewStatus(currentEnterpriseId, reviewEnterpriseId));
    }

    /**
     * 员工审核详情
     *
     * @return
     */
    @GetMapping("/staff/review/detail")
    public ResultJson reviewDetail(@RequestHeader("industryId") Integer industryId,
                                   @RequestParam("recordId") Integer recordId,
                                   @RequestParam("currentEnterpriseId") Integer currentEnterpriseId) {
        return ResultJson.success(staffService.reviewDetail(recordId, industryId, currentEnterpriseId));
    }

    private String getFilePath(String fileName){
        String basePath = null;
        try {
            basePath = ResourceUtils.getURL("classpath:").getPath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return basePath + "template/personal/" + fileName;
    }

    private ImportResult importHandler(Project project, List<StaffExcelDTO> staffExcelDTOS, Account account, String errorId, String fileName,Integer enterpriseId,Integer industryId) {
        List<StaffExcelDTO> rightCollect = new ArrayList<>();
        List<StaffExcelErrorDTO> errorList = new ArrayList<>();
        //Integer enterpriseId = project.getEnterpriseId();
        List<String> spaceNames = new ArrayList<>();
        List<String> orgCodes = new ArrayList<>();
        // 数据校验
        dataCheck(staffExcelDTOS, errorList, rightCollect, orgCodes,spaceNames, enterpriseId);
        List<StaffDTO> staffDTOS = new ArrayList<>(rightCollect.size());

        // 排除库中重复的身份证
        List<String> newIdCards = rightCollect.stream().filter(i -> StringUtils.isNotEmpty(i.getIdCard())).map(j -> j.getIdCard()).collect(Collectors.toList());
        if (!newIdCards.isEmpty()) {
            QueryWrapper<Staff> staffQueryWrapper = new QueryWrapper<>();
            staffQueryWrapper.select("id", "card_no");
            staffQueryWrapper.in("card_no", newIdCards);
            staffQueryWrapper.eq("is_deleted", false);
            staffQueryWrapper.eq("card_type", CredentialsEnum.ID_CARD);
            List<Staff> existIdCards = staffService.list(staffQueryWrapper);
            if (!existIdCards.isEmpty()) {
                List<StaffExcelDTO> needToRemove = rightCollect.stream().filter(i -> existIdCards.contains(i.getIdCard())).collect(Collectors.toList());
                for (StaffExcelDTO staffExcelDTO : needToRemove) {
                    StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                    BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                    staffExcelError.setReason("身份证重复");
                    errorList.add(staffExcelError);
                }
                rightCollect.removeAll(needToRemove);
            }
        }

        List<String> positionName = new ArrayList<>();
        List<String> businessNames = new ArrayList<>();
        List<String> higherUpNames = new ArrayList<>();
        //权限组中的项目和角色
        List<String> projectNames = new ArrayList<>();
        List<String> roleNames = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(rightCollect)) {
            for (StaffExcelDTO staffExcelDTO : rightCollect) {
                if (StringUtils.isNotEmpty(staffExcelDTO.getPosition())) {
                    positionName.add(staffExcelDTO.getPosition());
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getBusinessName())) {
                    businessNames.add(staffExcelDTO.getBusinessName());
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getHigherUpName())) {
                    higherUpNames.add(staffExcelDTO.getHigherUpName());
                }
                for (int i = 0; i < staffExcelDTO.getPermissionGroupDTOS().size(); i++) {
                    if (CollectionUtils.isNotEmpty(staffExcelDTO.getPermissionGroupDTOS().get(i).getProjectNames())) {
                        projectNames.addAll(staffExcelDTO.getPermissionGroupDTOS().get(i).getProjectNames());
                    }
                    if (CollectionUtils.isNotEmpty(staffExcelDTO.getPermissionGroupDTOS().get(i).getRoleNames())) {
                        roleNames.addAll(staffExcelDTO.getPermissionGroupDTOS().get(i).getRoleNames());
                    }
                }
            }
        }
        //查询空间路址
        Map<String, Organization> spaceMap = getOrganization(spaceNames, project.getEnterpriseId());
        // 查询组织
        Map<String, Organization> stringOrganizationMap = getOrgByCode(orgCodes, enterpriseId);
        // 岗位
        Map<String, Integer> positionMap = getPosition(positionName, enterpriseId);
        // 业务类型
        Map<String, Integer> businessMap = getBusinessMap(businessNames);
        // 直接上级
        Map<String, Integer> higherUpMap = getHigherUp(higherUpNames, account);
        // 获取空间id
        List<Integer> spaceTypeId = organizationTypeService.spaceIds();
        //查询项目权限
        Map<String, Project> projectMap = getProject(projectNames, getEntId(enterpriseId));
        //查询角色（只有企业角色了）
        Map<String, Integer> roleMap = getEnterpriseRoles(roleNames, enterpriseId);
        //入驻企业查询租赁空间、运营商查询所有空间
        Enterprise enterprise = enterpriseService.findById(enterpriseId);
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        if (enterprise.getType().contains(EnterpriseTypeEnum.OPERATOR.id.toString())) {
            organizationQueryWrapper.eq("enterprise_id", enterpriseId);
            organizationQueryWrapper.in("type", spaceTypeId);
        } else if (enterprise.getType().contains(EnterpriseTypeEnum.ENTER.id.toString())) {
            EnterpriseQuery enterpriseQuery = new EnterpriseQuery();
            enterpriseQuery.setIdList(Collections.singletonList(enterpriseId));
            List<EnterpriseSpace> spaces = enterpriseSpaceService.getEnterpriseSpace(enterpriseQuery).getResult();
            organizationQueryWrapper.in("id", spaces.stream().map(EnterpriseSpace::getOrganizationId).collect(Collectors.toList()));
        }
        List<Integer> organizationList = organizationService.list(organizationQueryWrapper).stream().map(Organization::getId).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(rightCollect)){
            for (StaffExcelDTO staffExcelDTO : rightCollect) {
                //从权限组获取角色+项目
                List<PermissionGroupDTO> groupDTOS = staffExcelDTO.getPermissionGroupDTOS();
                List<String> proNames = new ArrayList<>();
                List<String> roNames = new ArrayList<>();
                //权限组信息补全
                for (int j = 0; j < groupDTOS.size(); j++) {
                    roNames.addAll(groupDTOS.get(j).getRoleNames());
                    List<Integer> roIds = new ArrayList<>();
                    for (int i = 0; i < groupDTOS.get(j).getRoleNames().size(); i++) {
                        if (StringUtils.isEmpty(groupDTOS.get(j).getRoleNames().get(i))) {
                            continue;
                        }
                        roIds.add(roleMap.get(groupDTOS.get(j).getRoleNames().get(i)));
                    }
                    groupDTOS.get(j).setRoleList(roIds);
                    List<Integer> proIds = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(groupDTOS.get(j).getProjectNames())) {
                        proNames.addAll(groupDTOS.get(j).getProjectNames());
                        for (int i = 0; i < groupDTOS.get(j).getProjectNames().size(); i++) {
                            if (StringUtils.isEmpty(groupDTOS.get(j).getProjectNames().get(i))) {
                                continue;
                            }
                            try {
                                proIds.add(projectMap.get(groupDTOS.get(j).getProjectNames().get(i)).getId());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        groupDTOS.get(j).setProjectList(proIds);
                    }
                }
                final Map<String, Integer> roMap = roleMap;
                List<Integer> roleIds = roNames.stream().distinct().map(i -> roMap.get(i)).filter(i -> i != null).collect(Collectors.toList());
                // 设置角色员工角色信息
                if (CollectionUtils.isEmpty(roleIds)) {
                    StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                    BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                    staffExcelError.setReason("缺少角色信息");
                    errorList.add(staffExcelError);
                    continue;
                }
                staffExcelDTO.setRoleIds(roleIds);
                List<Integer> projectIds = new ArrayList<>(proNames.size());
                for (String string : proNames) {
                    if (null != projectMap.get(string)) {
                        projectIds.add(projectMap.get(string).getId());
                    }
                }
                String orgCode = staffExcelDTO.getOrgCode();
                List<String> orgCodeList = Arrays.asList(orgCode.split(","));
                List<Integer> orgIds = new ArrayList<>();
                for (String s : orgCodeList) {
                    Organization organization1 = stringOrganizationMap.get(s);
                    if (null != organization1) {
                        orgIds.add(organization1.getId());
                    }
                }

                StaffDTO staffDTO = new StaffDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffDTO);
                //权限组
                staffDTO.setPermissionGroupDTOs(groupDTOS);
                //项目权限
                staffDTO.setProjectIds(projectIds);
                // 组织
                if (orgIds.isEmpty()){
                    StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                    BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                    staffExcelError.setReason("组织编码错误");
                    errorList.add(staffExcelError);
                    continue;
                }
                staffDTO.setOrgIds(orgIds);
                // 企业
                staffDTO.setEnterpriseId(Arrays.asList(enterpriseId));
                // 性别
                if (StringUtils.isNotEmpty(staffExcelDTO.getSex())) {
                    staffDTO.setSex(staffExcelDTO.getSex().equals("男") ? (short) 1 : (short) 0);
                } else {
                    staffDTO.setSex((short) 1);
                }
                // 岗位
                if (StringUtils.isNotEmpty(staffExcelDTO.getPosition())) {
                    staffDTO.setPositionId(positionMap.get(staffExcelDTO.getPosition()));
                }
                // 员工类型 状态
                try {
                    staffDTO.setStaffType(StaffTypeEnum.desOf(staffExcelDTO.getStaffTypeName()).id);
                    staffDTO.setStaffState(StaffStateEnum.desOf(staffExcelDTO.getStaffStateName()).id);
                } catch (Exception de) {
                    de.printStackTrace();
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getWorkCode())) {
                    staffDTO.setWorkCode(staffExcelDTO.getWorkCode());
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getPoliticsStatusName())) {
                    try {
                        staffDTO.setPoliticsStatus(PoliticalOutlookEnum.findEnumByName(staffExcelDTO.getPoliticsStatusName()));
                    } catch (Exception e) {
                        log.warn(e.getMessage());
                    }
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getNationName())) {
                    try {
                        staffDTO.setNation(NationTypeEnum.findEnumByName(staffExcelDTO.getNationName()));
                    } catch (Exception e) {
                        log.warn(e.getMessage());
                    }
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getEducationalLevelName())) {
                    try {
                        staffDTO.setEducationalLevel(EducationLevelEnum.findEnumByName(staffExcelDTO.getEducationalLevelName()));
                    } catch (Exception e) {
                        log.warn(e.getMessage());
                    }
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getBirthday())) {
                    try {
                        staffDTO.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(staffExcelDTO.getBirthday()));
                    } catch (ParseException e) {
                        log.warn(e.getMessage());
                    }
                }
                //业务类型
                if (StringUtils.isNotEmpty(staffExcelDTO.getBusinessName())) {
                    List<Integer> businessIds = new ArrayList<>();
                    businessIds.add(businessMap.get(staffExcelDTO.getBusinessName()));
                    staffDTO.setBusinessIds(businessIds);
                }
                // 入职时间
                if (StringUtils.isNotEmpty(staffExcelDTO.getJoinTime())) {
                    try {
                        staffDTO.setJoinTime(new SimpleDateFormat("yyyy-MM-dd").parse(staffExcelDTO.getJoinTime()));
                    } catch (ParseException e) {
                        log.warn(e.getMessage());
                    }
                }
                //参加工作时间
                if (StringUtils.isNotEmpty(staffExcelDTO.getWorkingTime())) {
                    try {
                        staffDTO.setWorkingTime(new SimpleDateFormat("yyyy-MM-dd").parse(staffExcelDTO.getWorkingTime()));
                    } catch (ParseException e) {
                        log.warn(e.getMessage());
                    }
                }
                // 直接上级
                if (StringUtils.isNotEmpty(staffExcelDTO.getHigherUpName())) {
                    staffDTO.setHigherUp(higherUpMap.get(staffExcelDTO.getHigherUpName()));
                }
                // 关联空间
                if (StringUtils.isNotEmpty(staffExcelDTO.getSpaces())) {
                    List<Integer> spaceIds = new ArrayList<>();
                    for (String s : staffExcelDTO.getSpaces().split(",")) {
                        Organization organization1 = spaceMap.get(s);
                        //增加判断该空间是否是入驻企业下的租赁空间 or 运营商下的空间
                        if (null != organization1 && spaceTypeId.contains(organization1.getType())
                                && projectIds.contains(organization1.getProjectId())
                                && organizationList.contains(organization1.getId())) {
                            spaceIds.add(organization1.getId());
                        }
                    }
                    staffDTO.setSpaceIds(spaceIds);
                }
                if (StringUtils.isNotEmpty(staffExcelDTO.getIdCard())) {
                    staffDTO.setCardNo(staffExcelDTO.getIdCard());
                    staffDTO.setCardType(CredentialsEnum.ID_CARD);
                }
                staffDTOS.add(staffDTO);
                ResultJson resultJson = null;
                try {
                    QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("phone", staffDTO.getPhone());
                    queryWrapper.eq("is_deleted", 0);
                    List<Account> accounts = accountDao.selectList(queryWrapper);
                    if (CollectionUtils.isNotEmpty(accounts)) {
                        StaffQuery staffQuery = new StaffQuery();
                        staffQuery.setEnterpriseId(enterpriseId);
                        staffQuery.setAccountId(accounts.get(0).getId());
                        StaffDTO one = staffService.one(staffQuery);
                        if (one == null) {
                            //有账号没员工
                            resultJson = staffService.create(staffDTO, account);
                        } else {
                            //有账号有员工
                            staffDTO.setId(one.getId());
                            staffDTO.setCurrentIndustryId(industryId);
                            resultJson = staffService.edit(staffDTO, account);
                        }
                    } else {
                        //没账号
                        resultJson = staffService.create(staffDTO, account);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                    BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                    staffExcelError.setReason(e.getMessage());
                    errorList.add(staffExcelError);
                    continue;
                }
                if (!resultJson.getState()) {
                    StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                    BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                    staffExcelError.setReason(resultJson.getMessage());
                    errorList.add(staffExcelError);
                    continue;
                }
            }
        }
        return errorHandler(account,errorList, fileName, errorId, enterpriseId, staffExcelDTOS.size() - errorList.size(), errorList.size(), staffExcelDTOS.size());
    }

    private ImportResult errorHandler(Account account,List<StaffExcelErrorDTO> errorList, String fileName, String errorId, Integer enterpriseId, Integer right, Integer error, Integer total){
        StaffExcelImport staffExcelImport = null;
        ImportResult result = null;
        Integer msgSuccess = null;
        Integer msgError = null;
        if(errorList.isEmpty()){
            staffExcelImport = new StaffExcelImport();
            staffExcelImport.setAllRight(true);
            staffExcelImport.setFileName(fileName);
            staffExcelImport.setResult("全部成功，共" + total);
            staffExcelImportService.save(staffExcelImport);
            result = new ImportResult(total, total, 0);
            msgSuccess = total;
            msgError = 0;
        }else{
            List<StaffExcelError> errorList1 = new ArrayList<>(errorList.size());
            for (StaffExcelErrorDTO staffExcelErrorDTO : errorList) {
                StaffExcelError staffExcelError = new StaffExcelError();
                staffExcelError.setReason(staffExcelErrorDTO.getReason());
                staffExcelError.setObj(JSONObject.toJSONString(staffExcelErrorDTO));
                staffExcelError.setFileId(errorId);
                errorList1.add(staffExcelError);
            }
            staffExcelErrorService.saveBatch(errorList1);
            staffExcelImport = new StaffExcelImport();
            staffExcelImport.setAllRight(false);
            staffExcelImport.setFileName(fileName);
            staffExcelImport.setFileId(errorId);
            staffExcelImport.setResult("成功" + right +"，失败"+ errorList.size() +"，共"+ total);
            staffExcelImport.setEnterpriseId(enterpriseId);
            staffExcelImportService.save(staffExcelImport);
            result = new ImportResult(total, right, error);
            msgSuccess = right;
            msgError = error;
        }
        // 通知用户上传完毕了
        NoticeData noticeData = new NoticeData();
        noticeData.setTitle("UPLOAD_STAFF_FINISHED");
        Map<String, String> map = new HashMap<>();
        map.put("total", String.valueOf(total));
        map.put("success",String.valueOf(msgSuccess));
        map.put("error", String.valueOf(msgError));
        map.put("fileId", errorId);
        map.put("recordId", String.valueOf(staffExcelImport.getId()));
        noticeData.setParams(map);
        // 消息分类
        noticeData.setCategory(Arrays.asList("staff_import"));
        log.info("通知用户 {} 记录id {} 已经上传完成了", account.getId(), staffExcelImport.getId());
        try {
            Target target = new Target();
            target.setReceivers(Arrays.asList(account.getId().toString()));
            ResultJson resultJson = messageCentService.send("websocket", noticeData, target);
            log.info("staffImport消息发送结果 {}", JSONObject.toJSONString(resultJson));
        }catch (Exception e){
            log.error("staffImport上传完毕，通知用户失败了 {}", e.getMessage());
        }
        return result;
    }

    /**
     * 获得运营商企业id
     * @return
     */
    private Integer getEntId(Integer enterpriseId){
        Integer entId = enterpriseId;
        //企业嵌套不超过5层
        for (int i = 0; i < 5; i++) {
            //判断当前id是不是运营商企业id
            QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
            entQueryWrapper.in("id", entId);
            List<Enterprise> entList = enterpriseDao.selectList(entQueryWrapper);
            if(CollectionUtil.isNotEmpty(entList)){
                Enterprise enterprise = entList.get(0);
                //获得运营商企业id
                if(enterprise.getType() != null && enterprise.getType().contains(EnterpriseTypeEnum.OPERATOR.id.toString())){
                    return enterprise.getId();
                }
                entId = enterprise.getParentId();
            }
        }
        return enterpriseId;
    }

    private Map<String, Integer> getBusinessMap(List<String> businessNames) {
        Map<String, Integer> businessMap = new HashMap<>();
        if(!businessNames.isEmpty()){
            QueryWrapper<StaffBusinessType> staffBusinessTypeQueryWrapper = new QueryWrapper<>();
            staffBusinessTypeQueryWrapper.select("name", "id");
            staffBusinessTypeQueryWrapper.in("name", businessNames.stream().distinct().collect(Collectors.toList()));
            List<StaffBusinessType> list = staffBusinessTypeService.list(staffBusinessTypeQueryWrapper);
            if(!list.isEmpty()){
                businessMap = list.stream().collect(Collectors.toMap(StaffBusinessType::getName, StaffBusinessType::getId));
            }
        }
        return businessMap;
    }

    /**
     * 查詢企業角色
     * @param enterpriseRoleName
     * @param enterpriseId
     * @return
     */
    private Map<String, Integer> getEnterpriseRoles(List<String> enterpriseRoleName, Integer enterpriseId){
        Map<String, Integer> enterpriseRoleMap = new HashMap<>();
        if(!enterpriseRoleName.isEmpty()){
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setEnterpriseIdList(Arrays.asList(enterpriseId));
            roleQuery.setNames(enterpriseRoleName.stream().distinct().collect(Collectors.toList()));
            roleQuery.setGrade(BusinessType.ENTERPRISE.code);
            List<Role> enterpriseRoles = roleService.getList(roleQuery);
            enterpriseRoleMap = enterpriseRoles.stream().collect(Collectors.toMap(Role::getName, Role::getId));
        }
        return enterpriseRoleMap;
    }

    /**
     * 项目角色
     * @param projectRoleName
     * @param projectId
     * @return
     */
    private Map<String, Integer> getProjectRoles(List<String> projectRoleName, Integer projectId){
        Map<String, Integer> projectRoleMap = new HashMap<>();
        if(!projectRoleName.isEmpty()){
            RoleQuery roleQuery1 = new RoleQuery();
            roleQuery1.setProjectIdList(Arrays.asList(projectId));
            roleQuery1.setNames(projectRoleName.stream().distinct().collect(Collectors.toList()));
            roleQuery1.setGrade(BusinessType.PROJECT.code);
            List<Role> projectRoles = roleService.getList(roleQuery1);
            projectRoleMap = projectRoles.stream().collect(Collectors.toMap(Role::getName, Role::getId));
        }
        return projectRoleMap;
    }

    /**
     * 岗位
     * @param positionName
     * @param enterpriseId
     * @return
     */
    private Map<String, Integer> getPosition(List<String> positionName, Integer enterpriseId){
        Map<String, Integer> positionMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(positionName)){
            QueryWrapper<Position> positionQueryWrapper = new QueryWrapper<>();
            positionQueryWrapper.select("id", "name");
            positionQueryWrapper.in("name", positionName.stream().distinct().collect(Collectors.toList()));
            positionQueryWrapper.eq("enterprise_id", enterpriseId);
            List<Position> list = positionService.list(positionQueryWrapper);
            if(!list.isEmpty()){
                positionMap = list.stream().collect(Collectors.toMap(Position::getName, Position::getId,(s,s2)->s2));
            }
        }
        return positionMap;
    }

    /**
     * 根据编码获取组织
     */
    private Map<String, Organization> getOrgByCode(List<String> orgCode, Integer enterpriseId){
        if(CollectionUtils.isEmpty(orgCode) || enterpriseId == null){
            return new HashMap<>();
        }
        List<String> codes = orgCode.stream().distinct().collect(Collectors.toList());
        QueryWrapper<Organization> queryWrapper = new QueryWrapper();
        queryWrapper.eq("enterprise_id",enterpriseId);
        queryWrapper.in("code",codes);
        List<Organization> list = organizationService.list(queryWrapper);
        if(CollectionUtils.isEmpty(list)){
            return new HashMap<>();
        }
        Map<String,Organization> result = new HashMap<>();
        for(Organization vo:list){
            if(vo != null && StringUtils.isNotEmpty(vo.getCode())) {
                result.put(vo.getCode(), vo);
            }
        }
        return result;
    }

    /**
     * 组织
     * @param originalOrgName
     * @param enterpriseId
     * @return
     */
    private Map<String, Organization> getOrganization(List<String> originalOrgName, Integer enterpriseId){
        List<String> orgName1 = originalOrgName.stream().distinct().collect(Collectors.toList());
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.setChainNames(orgName1);
        organizationQuery.withEnterpriseId(enterpriseId);
        organizationQuery.setSplitChar("/");
        return organizationService.listByChainName(organizationQuery);
    }

    private Map<String, Integer> getHigherUp(List<String> higherUpNames, Account account){
        Map<String, Integer> higherUpMap = new HashMap<>();
        if(!higherUpNames.isEmpty()){
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            accountQueryWrapper.select("id", "phone");
            accountQueryWrapper.in("phone", higherUpNames);
            accountQueryWrapper.eq("develop_id", account.getDevelopId());
            accountQueryWrapper.eq("is_deleted",false);
            List<Account> list = accountService.list(accountQueryWrapper);
            if(!list.isEmpty()){
                higherUpMap = list.stream().collect(Collectors.toMap(Account::getPhone, Account::getId,(item1,item2) ->item1));
            }
        }
        return higherUpMap;
    }

    private ImportResult errorHandler(List<StaffExcelErrorDTO> errorList, String fileName, String errorId, Integer enterpriseId, Integer right, Integer error, Integer total){
        if(errorList.isEmpty()){
            StaffExcelImport staffExcelImport = new StaffExcelImport();
            staffExcelImport.setAllRight(true);
            staffExcelImport.setFileName(fileName);
            staffExcelImport.setResult("全部成功，共" + total);
            staffExcelImportService.save(staffExcelImport);
            return new ImportResult(total, total, 0);
        }else{
            List<StaffExcelError> errorList1 = new ArrayList<>(errorList.size());
            for (StaffExcelErrorDTO staffExcelErrorDTO : errorList) {
                StaffExcelError staffExcelError = new StaffExcelError();
                staffExcelError.setReason(staffExcelErrorDTO.getReason());
                staffExcelError.setObj(JSONObject.toJSONString(staffExcelErrorDTO));
                staffExcelError.setFileId(errorId);
                errorList1.add(staffExcelError);
            }
            staffExcelErrorService.saveBatch(errorList1);
            StaffExcelImport staffExcelImport = new StaffExcelImport();
            staffExcelImport.setAllRight(false);
            staffExcelImport.setFileName(fileName);
            staffExcelImport.setFileId(errorId);
            staffExcelImport.setResult("成功" + right +"，失败"+ errorList.size() +"，共"+ total);
            staffExcelImport.setEnterpriseId(enterpriseId);
            staffExcelImportService.save(staffExcelImport);
            return new ImportResult(total, right, error);
        }
    }

    private Map<String, Project> getProject(List<String> projectNames, Integer enterpriseId){
        projectNames = projectNames.stream().distinct().collect(Collectors.toList());
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.setProjectNames(projectNames);
        projectQuery.setEnterpriseId(enterpriseId);
        List<Project> projects = projectService.list(projectQuery, null);
        return projects.stream().collect(Collectors.toMap(Project::getName, Function.identity()));
    }

    private void dataCheck(List<StaffExcelDTO> staffExcelDTOS, List<StaffExcelErrorDTO> errorList, List<StaffExcelDTO> rightCollect, List<String> orgCodes, List<String> spaceNames, Integer enterpriseId){
        final String entRoleType = "企业角色";
        final String proRoleType = "项目角色";
        Map<String, Object> phoneCheck = new HashMap<>();
        Map<String, Object> loginNameCheck = new HashMap<>();
        Map<String, Object> idCardCheck = new HashMap<>();
        for (StaffExcelDTO staffExcelDTO : staffExcelDTOS) {
            if(StringUtils.isEmpty(staffExcelDTO.getName())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("姓名不存在");
                errorList.add(staffExcelError);
                continue;
            }
            if(StringUtils.isEmpty(staffExcelDTO.getPhone())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("手机号不存在");
                errorList.add(staffExcelError);
                continue;
            }
            if(StringUtils.isEmpty(staffExcelDTO.getOrgCode())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("组织不存在");
                errorList.add(staffExcelError);
                continue;
            }
            if (CollectionUtils.isEmpty(staffExcelDTO.getPermissionGroupDTOS())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("权限组不存在");
                errorList.add(staffExcelError);
                continue;
            }else {
                if(StringUtils.isEmpty(staffExcelDTO.getPermissionGroupDTOS().get(0).getRoleNames().toString())){
                    StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                    BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                    staffExcelError.setReason("角色不存在");
                    errorList.add(staffExcelError);
                    continue;
                }else{
                    //判断是否包含企管
                    List<String> roleNames = new ArrayList<>();
                    for(PermissionGroupDTO vo :staffExcelDTO.getPermissionGroupDTOS()){
                        roleNames.addAll(vo.getRoleNames());
                    }
                    if(CollectionUtils.isNotEmpty(roleNames)) {
                        RoleQuery roleQuery = new RoleQuery();
                        roleQuery.setEnterpriseIdList(Arrays.asList(enterpriseId));
                        roleQuery.setNames(roleNames);
                        roleQuery.setGrade(BusinessType.ENTERPRISE.code);
                        roleQuery.setType(RoleTypeEnum.MANAGER.code);
                        List<Role> enterpriseRoles = roleService.getList(roleQuery);
                        if (CollectionUtils.isNotEmpty(enterpriseRoles)) {
                            StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                            BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                            staffExcelError.setReason("角色存在企管");
                            errorList.add(staffExcelError);
                            continue;
                        }
                    }
                }
            }
            if (CollectionUtils.isEmpty(staffExcelDTO.getPermissionGroupDTOS().get(0).getProjectNames())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("项目不存在");
                errorList.add(staffExcelError);
                continue;
            }
            if (StringUtils.isEmpty(staffExcelDTO.getSpaces())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("空间不存在");
                errorList.add(staffExcelError);
                continue;
            }
            if(StringUtils.isNotEmpty(staffExcelDTO.getIdCard()) && !ValidatorUtil.isIDCard(staffExcelDTO.getIdCard())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("身份证错误");
                errorList.add(staffExcelError);
                continue;
            }
            // excel重复判断
            if(null != phoneCheck.get(staffExcelDTO.getPhone())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("手机号重复");
                errorList.add(staffExcelError);
                continue;
            }
            if(null != loginNameCheck.get(staffExcelDTO.getLoginName())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("用户名重复");
                errorList.add(staffExcelError);
                continue;
            }
            if(null != idCardCheck.get(staffExcelDTO.getIdCard())){
                StaffExcelErrorDTO staffExcelError = new StaffExcelErrorDTO();
                BeanUtils.copyProperties(staffExcelDTO, staffExcelError);
                staffExcelError.setReason("身份证重复");
                errorList.add(staffExcelError);
                continue;
            }

            phoneCheck.put(staffExcelDTO.getPhone(), 1);
            if(StringUtils.isNotEmpty(staffExcelDTO.getLoginName())){
                loginNameCheck.put(staffExcelDTO.getLoginName(), 1);
            }
            if(StringUtils.isNotEmpty(staffExcelDTO.getIdCard())){
                idCardCheck.put(staffExcelDTO.getIdCard(), 1);
            }
            rightCollect.add(staffExcelDTO);

            //获得组织code
            orgCodes.addAll(Arrays.asList(staffExcelDTO.getOrgCode().split(",")));
            if(StringUtils.isNotEmpty(staffExcelDTO.getSpaces())){
                List<String> spaceName = Arrays.asList(staffExcelDTO.getSpaces().split(","));
                spaceNames.addAll(spaceName);
            }
        }
    }

    @Getter
    @Setter
    class OrgStaffCount{

        private Integer orgId;

        private Integer count;
    }
}
